/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2013-2014 sagyf Yang. The Four Group.
 */

package app.kits.asyn;

import app.Const;
import app.dtos.ImportMemberDTO;
import app.models.member.Member;
import com.github.sog.config.StringPool;
import com.github.sog.kit.Tuple;
import com.github.sog.validator.ValidatorKit;
import com.google.common.base.Objects;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.io.Files;
import com.jfinal.plugin.ehcache.CacheKit;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;

/**
 * <p>
 * .
 * </p>
 *
 * @author sagyf yang
 * @version 1.0 2014-04-22 22:44
 * @since JDK 1.6
 */
public class MemberImportKit {

    public static final int CARD_NO_FIELD_INDEX = 0;
    public static final int NAME_FIELD_INDEX    = 2;
    public static final int PHONE_FIELD_INDEX   = 3;
    public static final int INTEGRAL_INDEX      = 6;

    private static final Splitter NEWLINE_SPLITTER = Splitter.on(StringPool.TAB);
    private static final Logger   logger           = LoggerFactory.getLogger(MemberImportKit.class);

    public static void import_excel(File excel_file) {
        try {
            HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(excel_file));
            final int numberOfSheets = workbook.getNumberOfSheets();
            for (int i = 0; i < numberOfSheets; i++) {
                if (workbook.getSheetAt(i).getPhysicalNumberOfRows() > 0) {
                    String[] _m;
                    HSSFSheet childSheet = workbook.getSheetAt(i);
                    int count_size = childSheet.getPhysicalNumberOfRows();
                    for (int rowi = 0; rowi < count_size; rowi++) {
                        final HSSFRow row = childSheet.getRow(rowi);
                        final int rowNum = row.getRowNum();
                        if (rowNum < 3) continue;


                        _m = new String[7];
                        for (int column_idx = 0; column_idx < rowNum; column_idx++) {
                            final HSSFCell cell = row.getCell(column_idx);
                            if (cell == null) break;
                            String val = StringPool.EMPTY;
                            switch (cell.getCellType()) {
                                case HSSFCell.CELL_TYPE_STRING:
                                    val = StringUtils.trim(cell.getStringCellValue());
                                    break;
                                case HSSFCell.CELL_TYPE_NUMERIC:
                                    val = cell.getNumericCellValue() + StringPool.EMPTY;
                                    break;
                                case HSSFCell.CELL_TYPE_BLANK:
                                    continue;
                                default:
                                    break;
                            }
                            if (Strings.isNullOrEmpty(val) || StringUtils.equals("null", val)) {
                                continue;
                            }
                            switch (column_idx) {
                                case CARD_NO_FIELD_INDEX:
                                    if (ValidatorKit.isAllNumber(val)) {
                                        _m[0] = val;
                                        _m[1] = StringPool.EMPTY;
                                        _m[2] = StringPool.EMPTY;
                                        _m[3] = StringPool.EMPTY;
                                        _m[4] = StringPool.EMPTY;
                                        _m[5] = StringPool.EMPTY;
                                        _m[6] = "0.0";
                                    } else {
                                        break;
                                    }
                                    break;
                                case NAME_FIELD_INDEX:
                                    _m[1] = val;
                                    break;
                                case PHONE_FIELD_INDEX:
                                    _m[2] = val;
                                    break;
                                case INTEGRAL_INDEX:
                                    _m[6] = val;
                                    break;
                                default:
                                    break;
                            }
                        }
                        if (_m[0] == null) {
                            continue;
                        }
                        Tuple<Boolean, String> rst = storage_member(_m, true);
                        storage_cache(rowi, _m, rst.getY(), excel_file.getName());
                    }
                }
            }
        } catch (IOException e) {
            logger.error("Importing membership information via Excel file error occurred!", e);
        }
    }


    public static void import_tsv(File tsv_file) {
        try {
            List<String> lines = Files.readLines(tsv_file, Charset.forName("GBK"));
            final int size = lines.size();
            for (int i = 0; i < size; i++) {
                if (i == 0) {
                    continue;
                }
                String line = lines.get(i);
                String[] _m = new String[6];
                List<String> line_data = NEWLINE_SPLITTER.splitToList(line);
                if (Strings.isNullOrEmpty(line_data.get(0))) {
                    continue;
                }
                //card_no
                _m[0] = line_data.get(0);
                // name
                _m[1] = line_data.get(1);
                // gender
                String gender = line_data.get(2);
                if (Strings.isNullOrEmpty(gender)) {
                    _m[3] = StringPool.EMPTY;
                } else {
                    _m[3] = StringUtils.equals("M", gender) ? "1" : "0";
                }
                // id_card
                _m[4] = line_data.get(3);
                // mail_address
                _m[5] = line_data.get(4);
                // phone
                _m[2] = line_data.get(5);

                Tuple<Boolean, String> rst = storage_member(_m, false);
                storage_cache(i, _m, rst.getY(), tsv_file.getName());
            }

        } catch (IOException e) {
            logger.error("By tsv file import membership information error!", e);
        }
    }

    public static Tuple<Boolean, String> storage_member(String[] _data, boolean in_integral) {
        if (_data[0] != null) {
            try {
                Member member = Member.dao.findByCardNo(String.valueOf(_data[0]));
                final boolean new_member = member == null;
                if (new_member && in_integral) {
                    return new Tuple<Boolean, String>(false, "会员基础信息不存在");
                }
                if (new_member) {
                    member = new Member();
                }

                member.set("card_no", _data[0]);
                if (in_integral) {
                    final String value = _data[6];
                    member.set("integral", value);
                    member.set("surplus", value);
                } else {
                    member.set("name", _data[1]);
                    member.set("phone", _data[2]);
                    member.set("gender", _data[3]);
                    member.set("id_card", _data[4]);
                    member.set("mail_address", _data[5]);
                }
                if (new_member) {
                    member.save();
                } else {
                    member.update();
                }
                return new Tuple<Boolean, String>(true, new_member ? " 新会员,导入成功!" : (in_integral ? "会员积分更新成功" : "已存在会员,更新成功!"));
            } catch (Exception e) {
                return new Tuple<Boolean, String>(false, "数据库导入会员出现错误!");
            }
        } else {
            return new Tuple<Boolean, String>(false, "会员卡号为空!");
        }
    }

    public static void storage_cache(int line, Object[] _data, String message, String cacheKey) {
        ImportMemberDTO memberDTO = new ImportMemberDTO(line, String.valueOf(Objects.firstNonNull(_data[1], StringPool.EMPTY)),
                String.valueOf(Objects.firstNonNull(_data[0], StringPool.EMPTY)), message);
        CacheKit.put(Const.CACHE_IMPORT_MASK + StringPool.DOLLAR + cacheKey, _data[0], memberDTO);
    }

}
